#include "formater_pattern.h"

#include <cstring>
#include <cctype>

#include <array>
#include <thread>

#include "os.h"
#include "helper_fmt.h"

namespace afcore {
namespace log {

/// @brief  填充范围
class CScopedPadder {
public:
  /// @brief  构造函数
  /// @param  wrapped_size    包裹指定大小
  /// @param  pad_info        填充信息
  /// @param  dest            fmt缓存
  CScopedPadder(size_t wrapped_size, const SPadInfo& pad_info, RMemoryBuf& dest)
    : pad_info_(pad_info)
    , dest_(dest) {
    remaining_pad_ = static_cast<int32_t>(pad_info.width) - static_cast<int32_t>(wrapped_size);
    if (remaining_pad_ <= 0) {
      // 如果包裹指定的大小小于填充的大小，析构的时候需要判断是否有截断标识
      return;
    }

    if (SPadInfo::kPadSideLeft == pad_info.side) {
      Pad(remaining_pad_);
      remaining_pad_ = 0;
    } else if (SPadInfo::kPadSideCenter == pad_info.side) {
      auto half_pad = remaining_pad_ / 2;
      auto reminder = remaining_pad_ & 0x1;
      Pad(half_pad);
      remaining_pad_ = half_pad + reminder;
    }
  }

  ~CScopedPadder() {
    if (remaining_pad_ >= 0) {
      Pad(remaining_pad_);
    } else if (pad_info_.truncate) {
      int32_t new_size = static_cast<int32_t>(dest_.size()) + remaining_pad_;
      dest_.resize(static_cast<size_t>(new_size));
    }
  }

private:
  /// @brief  填充
  /// @param  count       填充的长度
  void Pad(int32_t count) {
    AppendFmtStringView(RStringView(spaces_.data(), static_cast<size_t>(count)), dest_);
  }
private:
  const SPadInfo& pad_info_;  ///< 填充信息
  RMemoryBuf& dest_;          ///< fmt内存
  int32_t remaining_pad_ {0};    /// 剩余填充长度
  RStringView spaces_ {"                                                                ", 64}; ///< 填充空格字符
};

/// @brief  非范围填充 实现接口
class CNullScopedPadder {
public:
  CNullScopedPadder(size_t /*wrapped_size*/, const SPadInfo& /*pad_info*/, RMemoryBuf& /*dest*/) {}
};

//
// 日志名称与日志级别格式器
//

/// @brief  日志名称格式类
/// @tparam ScopedPadder    范围填充类
template<typename ScopedPadder>
class CFormatterLoggerName final
  : public CFormaterFlag {
public:
  /// @brief  显示构造函数
  /// @param  padinfo     填充信息
  explicit CFormatterLoggerName(SPadInfo padinfo)
    : CFormaterFlag(padinfo) {
  }

  /// @brief  日志名称格式化
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    ScopedPadder p(msg.logger_name.size(), padinfo_, dest);
    AppendFmtStringView(msg.logger_name, dest);
  }
};

/// @brief  日志缩写级别格式类
/// @tparam ScopedPadder    范围填充类
template<typename ScopedPadder>
class CFormatterLoggerShortLevel final
  : public CFormaterFlag {
public:
  /// @brief  显示构造函数
  /// @param  padinfo     填充信息
  explicit CFormatterLoggerShortLevel(SPadInfo padinfo)
    : CFormaterFlag(padinfo) {
  }

  /// @brief  日志级别缩写格式化
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    RStringView level_name{ToShortCStr(msg.level)};
    ScopedPadder p(level_name.size(), padinfo_, dest);
    AppendFmtStringView(level_name, dest);
  }
};

/// @brief  日志级别格式类
/// @tparam ScopedPadder    范围填充类
template<typename ScopedPadder>
class CFormatterLoggerLevel final
  : public CFormaterFlag {
public:
  /// @brief  显示构造函数
  /// @param  padinfo     填充信息
  explicit CFormatterLoggerLevel(SPadInfo padinfo)
    : CFormaterFlag(padinfo) {
  }

  /// @brief  日志级别格式化
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    RStringView& level_name = ToStringView(msg.level);
    ScopedPadder p(level_name.size(), padinfo_, dest);
    AppendFmtStringView(level_name, dest);
  }
};

//
// 时间类型格式器
//

/// @brief  转化为上午下午
/// @param  t   时间
/// @return 指定时间的上午还是下午 "PM" or "AM"
static const char* TimeToAmPm(const tm& t) {
  return t.tm_hour >= 12 ? "PM" : "AM";
}

/// @brief  时间转化为12小时制
/// @param  t   时间
/// @return 12小时制时间
static int TimeTo12h(const tm& t) {
  return t.tm_hour > 12 ? t.tm_hour - 12 : t.tm_hour;
}

/// @brief  星期缩写
static std::array<const char*, 7> g_log_time_short_weeks{{"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}};

/// @brief  星期缩写格式类
/// @tparam ScopedPadder    范围填充类
template<typename ScopedPadder>
class CFormatterTimeShortWeek final
  : public CFormaterFlag {
public:
  /// @brief  显示构造函数
  /// @param  padinfo     填充信息
  explicit CFormatterTimeShortWeek(SPadInfo padinfo)
    : CFormaterFlag(padinfo) {
  }

  /// @brief  星期缩写格式化
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    RStringView week_val{g_log_time_short_weeks[static_cast<size_t>(tm_time.tm_wday)]};
    ScopedPadder p(week_val.size(), padinfo_, dest);
    AppendFmtStringView(week_val, dest);
  }
};

/// @brief  星期全称
static std::array<const char*, 7> g_log_time_weeks{{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}};

/// @brief  星期格式类
/// @tparam ScopedPadder    范围填充类
template<typename ScopedPadder>
class CFormatterTimeWeek final
  : public CFormaterFlag {
public:
  /// @brief  显示构造函数
  /// @param  padinfo     填充信息
  explicit CFormatterTimeWeek(SPadInfo padinfo)
    : CFormaterFlag(padinfo) {
  }

  /// @brief  星期格式化
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    RStringView week_val{g_log_time_weeks[static_cast<size_t>(tm_time.tm_wday)]};
    ScopedPadder p(week_val.size(), padinfo_, dest);
    AppendFmtStringView(week_val, dest);
  }
};

/// @brief  月缩写
static std::array<const char*, 12> g_log_time_short_months{{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec"}};

/// @brief  月缩写格式类
/// @tparam ScopedPadder    范围填充类
template<typename ScopedPadder>
class CFormatterTimeShortMonth final
  : public CFormaterFlag {
public:
  /// @brief  显示构造函数
  /// @param  padinfo     填充信息
  explicit CFormatterTimeShortMonth(SPadInfo padinfo)
    : CFormaterFlag(padinfo) {
  }

  /// @brief  月缩写格式化
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    RStringView week_val{g_log_time_short_months[static_cast<size_t>(tm_time.tm_mon)]};
    ScopedPadder p(week_val.size(), padinfo_, dest);
    AppendFmtStringView(week_val, dest);
  }
};

/// @brief  月
static std::array<const char*, 12> g_log_time_months{{"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}};

/// @brief  月格式类
/// @tparam ScopedPadder    范围填充类
template<typename ScopedPadder>
class CFormatterTimeMonth final
  : public CFormaterFlag {
public:
  /// @brief  显示构造函数
  /// @param  padinfo     填充信息
  explicit CFormatterTimeMonth(SPadInfo padinfo)
    : CFormaterFlag(padinfo) {
  }

  /// @brief  月格式化
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    RStringView week_val{g_log_time_months[static_cast<size_t>(tm_time.tm_mon)]};
    ScopedPadder p(week_val.size(), padinfo_, dest);
    AppendFmtStringView(week_val, dest);
  }
};

/// @brief  日期缩写 (20/06/13) 2020年06月13日
template<typename ScopedPadder>
class CFormatterTimeShortDate final
  : public CFormaterFlag {
public:
  /// @brief  显示构造函数
  /// @param  padinfo     填充信息
  explicit CFormatterTimeShortDate(SPadInfo padinfo)
    : CFormaterFlag(padinfo) {
  }

  /// @brief  日期缩写格式化
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    const size_t field_size = 10;
    ScopedPadder p(field_size, padinfo_, dest);

    Pad2(tm_time.tm_year % 100, dest);
    dest.push_back('/');
    Pad2(tm_time.tm_mon + 1, dest);
    dest.push_back('/');
    Pad2(tm_time.tm_mday, dest);
  }
};

/// @brief  时间日期 (2020 Jun 13 Tue 21:49:18) 2020年6月13日 星期二 21:49:18
template<typename ScopedPadder>
class CFormatterTimeDate final
  : public CFormaterFlag {
public:
  /// @brief  显示构造函数
  /// @param  padinfo     填充信息
  explicit CFormatterTimeDate(SPadInfo padinfo)
    : CFormaterFlag(padinfo) {
  }

  /// @brief  时间日期格式化
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    const size_t field_size = 24;
    ScopedPadder p(field_size, padinfo_, dest);

    AppendFmtInt(tm_time.tm_year + 1900, dest);
    dest.push_back(' ');
    AppendFmtStringView(g_log_time_short_months[static_cast<size_t>(tm_time.tm_mon)], dest);
    dest.push_back(' ');
    AppendFmtInt(tm_time.tm_mday, dest);
    dest.push_back(' ');
    AppendFmtStringView(g_log_time_short_weeks[static_cast<size_t>(tm_time.tm_wday)], dest);
    dest.push_back(' ');

    Pad2(tm_time.tm_hour, dest);
    dest.push_back(':');
    Pad2(tm_time.tm_min, dest);
    dest.push_back(':');
    Pad2(tm_time.tm_sec, dest);
  }
};

/// @brief  年格式类 两位
/// @tparam ScopedPadder    范围填充类
template<typename ScopedPadder>
class CFormatterTimeShortYear final
  : public CFormaterFlag {
public:
  /// @brief  显示构造函数
  /// @param  padinfo     填充信息
  explicit CFormatterTimeShortYear(SPadInfo padinfo)
    : CFormaterFlag(padinfo) {
  }

  /// @brief  两位年格式化
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    const size_t filed_size = 2;
    ScopedPadder p(filed_size, padinfo_, dest);
    Pad2(tm_time.tm_year % 100, dest);
  }
};

/// @brief  年格式类 四位
/// @tparam ScopedPadder    范围填充类
template<typename ScopedPadder>
class CFormatterTimeYear final
  : public CFormaterFlag {
public:
  /// @brief  显示构造函数
  /// @param  padinfo     填充信息
  explicit CFormatterTimeYear(SPadInfo padinfo)
    : CFormaterFlag(padinfo) {
  }

  /// @brief  四位年格式化
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    const size_t filed_size = 4;
    ScopedPadder p(filed_size, padinfo_, dest);
    Pad2(tm_time.tm_year + 1900, dest);
  }
};

/// @brief  月格式类 1-12
/// @tparam ScopedPadder    范围填充类
template<typename ScopedPadder>
class CFormatterTimeMonthNum final
  : public CFormaterFlag {
public:
  /// @brief  显示构造函数
  /// @param  padinfo     填充信息
  explicit CFormatterTimeMonthNum(SPadInfo padinfo)
    : CFormaterFlag(padinfo) {
  }

  /// @brief  月格式化 1-12
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    const size_t filed_size = 2;
    ScopedPadder p(filed_size, padinfo_, dest);
    Pad2(tm_time.tm_mon + 1, dest);
  }
};

/// @brief  天格式类 1-31
/// @tparam ScopedPadder    范围填充类
template<typename ScopedPadder>
class CFormatterTimeDayNum final
  : public CFormaterFlag {
public:
  /// @brief  显示构造函数
  /// @param  padinfo     填充信息
  explicit CFormatterTimeDayNum(SPadInfo padinfo)
    : CFormaterFlag(padinfo) {
  }

  /// @brief  天格式化 1-31
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    const size_t filed_size = 2;
    ScopedPadder p(filed_size, padinfo_, dest);
    Pad2(tm_time.tm_mday, dest);
  }
};

/// @brief  小时格式类 24小时 0-23
/// @tparam ScopedPadder    范围填充类
template<typename ScopedPadder>
class CFormatterTimeHour24Num final
  : public CFormaterFlag {
public:
  /// @brief  显示构造函数
  /// @param  padinfo     填充信息
  explicit CFormatterTimeHour24Num(SPadInfo padinfo)
    : CFormaterFlag(padinfo) {
  }

  /// @brief  小时格式化 24小时 0-23
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    const size_t filed_size = 2;
    ScopedPadder p(filed_size, padinfo_, dest);
    Pad2(tm_time.tm_hour, dest);
  }
};

/// @brief  小时格式类 12小时 1-12
/// @tparam ScopedPadder    范围填充类
template<typename ScopedPadder>
class CFormatterTimeHour12Num final
  : public CFormaterFlag {
public:
  /// @brief  显示构造函数
  /// @param  padinfo     填充信息
  explicit CFormatterTimeHour12Num(SPadInfo padinfo)
    : CFormaterFlag(padinfo) {
  }

  /// @brief  小时格式化 12小时 1-12
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    const size_t filed_size = 2;
    ScopedPadder p(filed_size, padinfo_, dest);
    Pad2(TimeTo12h(tm_time), dest);
  }
};

/// @brief  分钟格式类 0-59
/// @tparam ScopedPadder    范围填充类
template<typename ScopedPadder>
class CFormatterTimeMinuteNum final
  : public CFormaterFlag {
public:
  /// @brief  显示构造函数
  /// @param  padinfo     填充信息
  explicit CFormatterTimeMinuteNum(SPadInfo padinfo)
    : CFormaterFlag(padinfo) {
  }

  /// @brief  分钟格式化 0-59
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    const size_t filed_size = 2;
    ScopedPadder p(filed_size, padinfo_, dest);
    Pad2(tm_time.tm_min, dest);
  }
};

/// @brief  秒格式类 0-59
/// @tparam ScopedPadder    范围填充类
template<typename ScopedPadder>
class CFormatterTimeSecondNum final
  : public CFormaterFlag {
public:
  /// @brief  显示构造函数
  /// @param  padinfo     填充信息
  explicit CFormatterTimeSecondNum(SPadInfo padinfo)
    : CFormaterFlag(padinfo) {
  }

  /// @brief  秒格式化 0-59
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    const size_t filed_size = 2;
    ScopedPadder p(filed_size, padinfo_, dest);
    Pad2(tm_time.tm_sec, dest);
  }
};

/// @brief  毫秒格式类
/// @tparam ScopedPadder    范围填充类
template<typename ScopedPadder>
class CFormatterTimeMilliSecondNum final
  : public CFormaterFlag {
public:
  /// @brief  显示构造函数
  /// @param  padinfo     填充信息
  explicit CFormatterTimeMilliSecondNum(SPadInfo padinfo)
    : CFormaterFlag(padinfo) {
  }

  /// @brief  毫秒格式化
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    auto millis = TimeFraction<RMilliseconds>(msg.time);
    const size_t filed_size = 3;
    ScopedPadder p(filed_size, padinfo_, dest);
    Pad3(static_cast<uint32_t>(millis.count()), dest);
  }
};

/// @brief  微秒格式类
/// @tparam ScopedPadder    范围填充类
template<typename ScopedPadder>
class CFormatterTimeMicroSecondNum final
  : public CFormaterFlag {
public:
  /// @brief  显示构造函数
  /// @param  padinfo     填充信息
  explicit CFormatterTimeMicroSecondNum(SPadInfo padinfo)
    : CFormaterFlag(padinfo) {
  }

  /// @brief  微秒格式化
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    auto micros = TimeFraction<RMicroseconds>(msg.time);
    const size_t filed_size = 6;
    ScopedPadder p(filed_size, padinfo_, dest);
    Pad6(static_cast<uint32_t>(micros.count()), dest);
  }
};

/// @brief  纳秒格式类
/// @tparam ScopedPadder    范围填充类
template<typename ScopedPadder>
class CFormatterTimeNanoSecondNum final
  : public CFormaterFlag {
public:
  /// @brief  显示构造函数
  /// @param  padinfo     填充信息
  explicit CFormatterTimeNanoSecondNum(SPadInfo padinfo)
    : CFormaterFlag(padinfo) {
  }

  /// @brief  纳秒格式化
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    auto nanos = TimeFraction<RNanoseconds>(msg.time);
    const size_t filed_size = 9;
    ScopedPadder p(filed_size, padinfo_, dest);
    Pad9(static_cast<uint32_t>(nanos.count()), dest);
  }
};

/// @brief  时间戳格式类
/// @tparam ScopedPadder    范围填充类
template<typename ScopedPadder>
class CFormatterTimestampNum final
  : public CFormaterFlag {
public:
  /// @brief  显示构造函数
  /// @param  padinfo     填充信息
  explicit CFormatterTimestampNum(SPadInfo padinfo)
    : CFormaterFlag(padinfo) {
  }

  /// @brief  时间戳格式化
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    const size_t filed_size = 10;
    ScopedPadder p(filed_size, padinfo_, dest);
    auto duration = msg.time.time_since_epoch();
    auto timestamp = std::chrono::duration_cast<RSeconds>(duration).count();
    AppendFmtInt(timestamp, dest);
  }
};

/// @brief  AM/PM格式类
/// @tparam ScopedPadder    范围填充类
template<typename ScopedPadder>
class CFormatterAmpm final
  : public CFormaterFlag {
public:
  /// @brief  显示构造函数
  /// @param  padinfo     填充信息
  explicit CFormatterAmpm(SPadInfo padinfo)
    : CFormaterFlag(padinfo) {
  }

  /// @brief  AM/PM格式化
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    const size_t filed_size = 2;
    ScopedPadder p(filed_size, padinfo_, dest);
    AppendFmtStringView(TimeToAmPm(tm_time), dest);
  }
};

/// @brief  十二小时制AM/PM格式类  11:24:44 pm
/// @tparam ScopedPadder    范围填充类
template<typename ScopedPadder>
class CFormatterTime12Ampm final
  : public CFormaterFlag {
public:
  /// @brief  显示构造函数
  /// @param  padinfo     填充信息
  explicit CFormatterTime12Ampm(SPadInfo padinfo)
    : CFormaterFlag(padinfo) {
  }

  /// @brief  十二小时制AM/PM格式化
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    const size_t filed_size = 11;
    ScopedPadder p(filed_size, padinfo_, dest);

    Pad2(TimeTo12h(tm_time), dest);
    dest.push_back(':');
    Pad2(tm_time.tm_min, dest);
    dest.push_back(':');
    Pad2(tm_time.tm_sec, dest);
    dest.push_back(' ');
    AppendFmtStringView(TimeToAmPm(tm_time), dest);
  }
};

/// @brief  二十四小时制格式类 23:30 小时:分钟
/// @tparam ScopedPadder    范围填充类
template<typename ScopedPadder>
class CFormatterTime24Short final
  : public CFormaterFlag {
public:
  /// @brief  显示构造函数
  /// @param  padinfo     填充信息
  explicit CFormatterTime24Short(SPadInfo padinfo)
    : CFormaterFlag(padinfo) {
  }

  /// @brief  二十四小时制格式化 小时:分钟
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    const size_t filed_size = 5;
    ScopedPadder p(filed_size, padinfo_, dest);

    Pad2(tm_time.tm_hour, dest);
    dest.push_back(':');
    Pad2(tm_time.tm_min, dest);
  }
};

/// @brief  二十四小时制格式类 ISO 8601 time  23:30:00
/// @tparam ScopedPadder    范围填充类
template<typename ScopedPadder>
class CFormatterTime24 final
  : public CFormaterFlag {
public:
  /// @brief  显示构造函数
  /// @param  padinfo     填充信息
  explicit CFormatterTime24(SPadInfo padinfo)
    : CFormaterFlag(padinfo) {
  }

  /// @brief  二十四小时制格式化
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    const size_t filed_size = 8;
    ScopedPadder p(filed_size, padinfo_, dest);

    Pad2(tm_time.tm_hour, dest);
    dest.push_back(':');
    Pad2(tm_time.tm_min, dest);
    dest.push_back(':');
    Pad2(tm_time.tm_sec, dest);
  }
};

//
// 线程
//

/// @brief  线程格式类
/// @tparam ScopedPadder    范围填充类
template<typename ScopedPadder>
class CFormatterThreadId final
  : public CFormaterFlag {
public:
  /// @brief  显示构造函数
  /// @param  padinfo     填充信息
  explicit CFormatterThreadId(SPadInfo padinfo)
    : CFormaterFlag(padinfo) {
  }

  /// @brief  线程格式化
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    const auto field_size = CountDigits(msg.thread_id);
    ScopedPadder p(field_size, padinfo_, dest);
    AppendFmtInt(msg.thread_id, dest);
  }
};

//
// 进程
//

/// @brief  进程格式类
/// @tparam ScopedPadder    范围填充类
template<typename ScopedPadder>
class CFormatterProcessId final
  : public CFormaterFlag {
public:
  /// @brief  显示构造函数
  /// @param  padinfo     填充信息
  explicit CFormatterProcessId(SPadInfo padinfo)
    : CFormaterFlag(padinfo) {
  }

  /// @brief  进程格式化
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    const auto pid = static_cast<uint32_t>(GetPid());
    auto field_size = CountDigits(pid);
    ScopedPadder p(field_size, padinfo_, dest);
    AppendFmtInt(pid, dest);
  }
};

//
// 日志信息
//

/// @brief  日志信息格式类
/// @tparam ScopedPadder    范围填充类
template<typename ScopedPadder>
class CFormatterLogInfo final
  : public CFormaterFlag {
public:
  /// @brief  显示构造函数
  /// @param  padinfo     填充信息
  explicit CFormatterLogInfo(SPadInfo padinfo)
    : CFormaterFlag(padinfo) {
  }

  /// @brief  日志信息格式化
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    ScopedPadder p(msg.playload.size(), padinfo_, dest);
    AppendFmtStringView(msg.playload, dest);
  }
};

/// @brief  字符格式类
class CFormatterChar final
  : public CFormaterFlag {
public:
  /// @brief  显示构造函数
  /// @param  ch      填充字符
  explicit CFormatterChar(char ch)
    : ch_(ch) {
  }

  /// @brief  字符格式化
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    dest.push_back(ch_);
  }
private:
  char ch_;   ///< 字符
};

/// @brief  字符串格式类
class CFormatterString final
  : public CFormaterFlag {
public:
  /// @brief  默认构造函数
  CFormatterString() = default;

  /// @brief  追加字符
  /// @param  ch      新添加的字符
  void AddChar(char ch) {
    str_ += ch;
  }

  /// @brief  字符格式化
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    AppendFmtStringView(str_, dest);
  }
private:
  std::string str_;   ///< 字符串
};

/// @brief  颜色开始格式类
class CFormatterColorStart final
  : public CFormaterFlag {
public:
  /// @brief  显示构造函数
  /// @param  padinfo     填充信息
  explicit CFormatterColorStart(SPadInfo padinfo)
    : CFormaterFlag(padinfo) {
  }

  /// @brief  颜色开始格式化
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    msg.color_range_start = dest.size();
  }
};

/// @brief  颜色结束格式类
class CFormatterColorEnd final
  : public CFormaterFlag {
public:
  /// @brief  显示构造函数
  /// @param  padinfo     填充信息
  explicit CFormatterColorEnd(SPadInfo padinfo)
    : CFormaterFlag(padinfo) {
  }

  /// @brief  颜色结束格式化
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    msg.color_range_end = dest.size();
  }
};

/// @brief  源文件定位格式类 源文件 文件名:行号
/// @tparam ScopedPadder    范围填充类
template<typename ScopedPadder>
class CFormatterSrcLocInfo final
  : public CFormaterFlag {
public:
  /// @brief  显示构造函数
  /// @param  padinfo     填充信息
  explicit CFormatterSrcLocInfo(SPadInfo padinfo)
    : CFormaterFlag(padinfo) {
  }

  /// @brief  源文件定位格式化
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    if (msg.source_info.Empty()) {
      return;
    }

    size_t text_size = padinfo_.Enabled() ? std::char_traits<char>::length(msg.source_info.filename) + CountDigits(msg.source_info.line) + 1 : 0;
    ScopedPadder p(text_size, padinfo_, dest);
    AppendFmtStringView(msg.source_info.filename, dest);
    dest.push_back(':');
    AppendFmtInt(msg.source_info.line, dest);
  }
};

/// @brief  源文件文件名不带路径格式类
/// @tparam ScopedPadder    范围填充类
template<typename ScopedPadder>
class CFormatterSrcShortFileName final
  : public CFormaterFlag {
public:
  /// @brief  显示构造函数
  /// @param  padinfo     填充信息
  explicit CFormatterSrcShortFileName(SPadInfo padinfo)
    : CFormaterFlag(padinfo) {
  }

  static const char* BaseName(const char* filename) {
    const char* rv = std::strrchr(filename, g_floder_sep);
    return nullptr != rv ? rv + 1 : filename;
  }

  /// @brief  源文件文件名不带路径格式化
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    if (msg.source_info.Empty()) {
      return;
    }

    auto filename = BaseName(msg.source_info.filename);
    size_t text_size = padinfo_.Enabled() ? std::char_traits<char>::length(filename) : 0;
    ScopedPadder p(text_size, padinfo_, dest);
    AppendFmtStringView(filename, dest);
  }
};

/// @brief  源文件文件名带路径格式类
/// @tparam ScopedPadder    范围填充类
template<typename ScopedPadder>
class CFormatterSrcFileName final
  : public CFormaterFlag {
public:
  /// @brief  显示构造函数
  /// @param  padinfo     填充信息
  explicit CFormatterSrcFileName(SPadInfo padinfo)
    : CFormaterFlag(padinfo) {
  }

  /// @brief  源文件文件名带路径格式化
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    if (msg.source_info.Empty()) {
      return;
    }

    size_t text_size = padinfo_.Enabled() ? std::char_traits<char>::length(msg.source_info.filename) : 0;
    ScopedPadder p(text_size, padinfo_, dest);
    AppendFmtStringView(msg.source_info.filename, dest);
  }
};

/// @brief  源文件行号格式类
/// @tparam ScopedPadder    范围填充类
template<typename ScopedPadder>
class CFormatterSrcLineNum final
  : public CFormaterFlag {
public:
  /// @brief  显示构造函数
  /// @param  padinfo     填充信息
  explicit CFormatterSrcLineNum(SPadInfo padinfo)
    : CFormaterFlag(padinfo) {
  }

  /// @brief  源文件行号格式化
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    if (msg.source_info.Empty()) {
      return;
    }

    auto field_size = CountDigits(msg.source_info.line);
    ScopedPadder p(field_size, padinfo_, dest);
    AppendFmtInt(msg.source_info.line, dest);
  }
};

/// @brief  源文件函数名格式类
/// @tparam ScopedPadder    范围填充类
template<typename ScopedPadder>
class CFormatterSrcFunctionName final
  : public CFormaterFlag {
public:
  /// @brief  显示构造函数
  /// @param  padinfo     填充信息
  explicit CFormatterSrcFunctionName(SPadInfo padinfo)
    : CFormaterFlag(padinfo) {
  }

  /// @brief  源文件函数名格式化
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    if (msg.source_info.Empty()) {
      return;
    }

    size_t text_size = padinfo_.Enabled() ? std::char_traits<char>::length(msg.source_info.funcname) : 0;
    ScopedPadder p(text_size, padinfo_, dest);
    AppendFmtStringView(msg.source_info.funcname, dest);
  }
};

/// @brief  日志时间差格式类
/// @tparam ScopedPadder    范围填充类
/// @tparam Units           单位
template<typename ScopedPadder, typename Units>
class CFormatterElapsed final
  : public CFormaterFlag {
public:
  /// @brief  显示构造函数
  /// @param  padinfo     填充信息
  explicit CFormatterElapsed(SPadInfo padinfo)
    : CFormaterFlag(padinfo)
    , last_message_time_(RClockLog::now()) {
  }

  /// @brief  日志时间差格式化
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    auto diff = (std::max)(msg.time - last_message_time_, RClockLog::duration::zero());
    auto diff_units = std::chrono::duration_cast<Units>(diff);
    last_message_time_ = msg.time;
    auto diff_count = static_cast<size_t>(diff_units.count());
    auto field_size = static_cast<size_t>(CountDigits(diff_count));
    ScopedPadder p(field_size, padinfo_, dest);
    AppendFmtInt(diff_count, dest);
  }
private:
  RClockLog::time_point last_message_time_;
};

/// @brief  默认完整格式类
class CFormatterFull final
  : public CFormaterFlag {
public:
  /// @brief  显示构造函数
  /// @param  padinfo     填充信息
  explicit CFormatterFull(SPadInfo padinfo)
    : CFormaterFlag(padinfo) {
  }

  /// @brief  默认完整格式化 [年-月-日 时:分:秒.毫秒] [日志名] [日志级别] [源文件信息] 日志信息
  /// @param  msg     日志信息
  /// @param  tm_time 日志时间
  /// @param  [out]   dest    fmt缓冲区
  void Format(const SLogMessage& msg, const std::tm& tm_time, RMemoryBuf& dest) override {
    using std::chrono::duration_cast;

    auto duration = msg.time.time_since_epoch();
    auto secs = duration_cast<RSeconds>(duration);

    if (cache_timestamp_ != secs || 0 == cached_datetime_.size()) {
      cached_datetime_.clear();
      cached_datetime_.push_back('[');
      AppendFmtInt(tm_time.tm_year + 1900, cached_datetime_);
      cached_datetime_.push_back('-');

      AppendFmtInt(tm_time.tm_mon + 1, cached_datetime_);
      cached_datetime_.push_back('-');

      AppendFmtInt(tm_time.tm_mday, cached_datetime_);
      cached_datetime_.push_back(' ');

      AppendFmtInt(tm_time.tm_hour, cached_datetime_);
      cached_datetime_.push_back(':');

      AppendFmtInt(tm_time.tm_min, cached_datetime_);
      cached_datetime_.push_back(':');

      AppendFmtInt(tm_time.tm_sec, cached_datetime_);
      cached_datetime_.push_back('.');

      cache_timestamp_ = secs;
    }
    dest.append(cached_datetime_.begin(), cached_datetime_.end());

    auto millis = TimeFraction<RMilliseconds>(msg.time);
    Pad3(static_cast<uint32_t>(millis.count()), dest);
    dest.push_back(']');
    dest.push_back(' ');

    if (msg.logger_name.size() > 0) {
      dest.push_back('[');
      AppendFmtStringView(msg.logger_name, dest);
      dest.push_back(']');
      dest.push_back(' ');
    }

    msg.color_range_start = dest.size();
    dest.push_back('[');
    RStringView level_view = ToStringView(msg.level);
    AppendFmtStringView(level_view, dest);
    dest.push_back(']');
    dest.push_back(' ');
    if (0 == level_view.size() % 2) {
      dest.push_back(' ');
    }

    if (!msg.source_info.Empty()) {
      dest.push_back('[');
      const char* filename = CFormatterSrcShortFileName<CNullScopedPadder>::BaseName(msg.source_info.filename);
      AppendFmtStringView(filename, dest);
      dest.push_back(':');
      AppendFmtInt(msg.source_info.line, dest);
      dest.push_back(']');
      dest.push_back(' ');
    }

    AppendFmtStringView(msg.playload, dest);
    msg.color_range_end = dest.size();
  }

private:
  RSeconds cache_timestamp_ {0};  ///< 缓存时间戳
  RMemoryBuf cached_datetime_;    ///< 缓存日期
};

CFormaterPattern::CFormaterPattern(std::string pattern, EPatternTimeType pattern_time_type,
  std::string eol, RCustomFlags custom_user_flags)
  : pattern_(std::move(pattern))
  , eol_(std::move(eol))
  , pattern_time_type_(pattern_time_type)
  , last_log_secs_(0)
  , custom_handlers_(std::move(custom_user_flags)) {
  std::memset(&cached_tm_, 0, sizeof(cached_tm_));
  AnalyzePattern(pattern_);
}

CFormaterPattern::CFormaterPattern(EPatternTimeType pattern_time_type, std::string eol)
  : pattern_("%+")
  , eol_(std::move(eol))
  , pattern_time_type_(pattern_time_type)
  , last_log_secs_(0) {
  std::memset(&cached_tm_, 0, sizeof(cached_tm_));
  formatters_.push_back(std::make_unique<CFormatterFull>(SPadInfo{}));
}

void CFormaterPattern::Format(const SLogMessage& msg, RMemoryBuf& dest) {
  auto secs = std::chrono::duration_cast<RSeconds>(msg.time.time_since_epoch());
  if (secs != last_log_secs_) {
    cached_tm_ = GetTime(msg);
    last_log_secs_ = secs;
  }

  for (auto& f : formatters_) {
    f->Format(msg, cached_tm_, dest);
  }

  AppendFmtStringView(eol_, dest);
}

RFormatterUptr CFormaterPattern::Clone() const {
  RCustomFlags cloned_custom_formatters;
  for (auto& iter : custom_handlers_) {
    cloned_custom_formatters[iter.first] = iter.second->Clone();
  }
  return std::make_unique<CFormaterPattern>(pattern_, pattern_time_type_, eol_, std::move(cloned_custom_formatters));
}

void CFormaterPattern::SetPattern(std::string pattern) {
  pattern_ = std::move(pattern);
  AnalyzePattern(pattern_);
}

std::tm CFormaterPattern::GetTime(const SLogMessage& msg) {
  if (EPatternTimeType::kPatternTimeTypeLocal ==  pattern_time_type_) {
    return fmt::localtime(RClockLog::to_time_t(msg.time));
  }
  return fmt::gmtime(RClockLog::to_time_t(msg.time));
}

template<typename Padder>
void CFormaterPattern::HandleFlag(char flag, SPadInfo pad_info) {
  auto iter = custom_handlers_.find(flag);
  if (custom_handlers_.end() != iter) {
    auto custom_handler = iter->second->Clone();
    custom_handler->SetPadInfo(pad_info);
    formatters_.push_back(std::move(custom_handler));
    return;
  }

  // 内置标志处理
  switch(flag) {
    case '+': // 默认
      { formatters_.push_back(std::make_unique<CFormatterFull>(pad_info)); }
      break;

    case 'n': // 日志名称
      { formatters_.push_back(std::make_unique<CFormatterLoggerName<Padder>>(pad_info)); }
      break;

    case 'L': // 日志级别缩写
      { formatters_.push_back(std::make_unique<CFormatterLoggerShortLevel<Padder>>(pad_info)); }
      break;

    case 'l': // 日志级别
      { formatters_.push_back(std::make_unique<CFormatterLoggerLevel<Padder>>(pad_info)); }
      break;

    case 'A': // 星期缩写
      { formatters_.push_back(std::make_unique<CFormatterTimeShortWeek<Padder>>(pad_info)); }
      break;

    case 'a': // 星期
      { formatters_.push_back(std::make_unique<CFormatterTimeWeek<Padder>>(pad_info)); }
      break;

    case 'B': // 月缩写
      { formatters_.push_back(std::make_unique<CFormatterTimeShortMonth<Padder>>(pad_info)); }
      break;

    case 'b': // 月
      { formatters_.push_back(std::make_unique<CFormatterTimeMonth<Padder>>(pad_info)); }
      break;

    case 'C': // 日期简写
      { formatters_.push_back(std::make_unique<CFormatterTimeShortDate<Padder>>(pad_info)); }
      break;

    case 'c': // 日期
      { formatters_.push_back(std::make_unique<CFormatterTimeDate<Padder>>(pad_info)); }
      break;

    case 'Y': // 年缩写
      { formatters_.push_back(std::make_unique<CFormatterTimeShortYear<Padder>>(pad_info)); }
      break;

    case 'y': // 年
      { formatters_.push_back(std::make_unique<CFormatterTimeYear<Padder>>(pad_info)); }
      break;

    case 'm': // 月 1-12
      { formatters_.push_back(std::make_unique<CFormatterTimeMonthNum<Padder>>(pad_info)); }
      break;

    case 'd': // 日 1-31
      { formatters_.push_back(std::make_unique<CFormatterTimeDayNum<Padder>>(pad_info)); }
      break;

    case 'h': // 小时 0-23
      { formatters_.push_back(std::make_unique<CFormatterTimeHour24Num<Padder>>(pad_info)); }
      break;

    case 'H': // 小时 1-12
      { formatters_.push_back(std::make_unique<CFormatterTimeHour12Num<Padder>>(pad_info)); }
      break;

    case 'M': // 分钟 0-59
      { formatters_.push_back(std::make_unique<CFormatterTimeMinuteNum<Padder>>(pad_info)); }
      break;

    case 'S': // 秒 0-59
      { formatters_.push_back(std::make_unique<CFormatterTimeSecondNum<Padder>>(pad_info)); }
      break;

    case 'E': // 毫秒
      { formatters_.push_back(std::make_unique<CFormatterTimeMilliSecondNum<Padder>>(pad_info)); }
      break;

    case 'F': // 微妙
      { formatters_.push_back(std::make_unique<CFormatterTimeMicroSecondNum<Padder>>(pad_info)); }
      break;

    case 'G': // 纳秒
      { formatters_.push_back(std::make_unique<CFormatterTimeNanoSecondNum<Padder>>(pad_info)); }
      break;

    case 't': // 时间戳
      { formatters_.push_back(std::make_unique<CFormatterTimestampNum<Padder>>(pad_info)); }
      break;

    case 'p': // AM/PM
      { formatters_.push_back(std::make_unique<CFormatterAmpm<Padder>>(pad_info)); }
      break;

    case 'r': // 十二小时制AM/PM格式类
      { formatters_.push_back(std::make_unique<CFormatterTime12Ampm<Padder>>(pad_info)); }
      break;

    case 'j': // 二十四小时制格式化 小时:分钟
      { formatters_.push_back(std::make_unique<CFormatterTime24Short<Padder>>(pad_info)); }
      break;

    case 'J': // 二十四小时制格式类 ISO 8601 time  23:30:00
      { formatters_.push_back(std::make_unique<CFormatterTime24<Padder>>(pad_info)); }
      break;

    case 'T': // 线程
      { formatters_.push_back(std::make_unique<CFormatterThreadId<Padder>>(pad_info)); }
      break;

    case 'P': // 进程
      { formatters_.push_back(std::make_unique<CFormatterProcessId<Padder>>(pad_info)); }
      break;

    case 'v': // 日志信息
      { formatters_.push_back(std::make_unique<CFormatterLogInfo<Padder>>(pad_info)); }
      break;

    case '%': // 字符
      { formatters_.push_back(std::make_unique<CFormatterChar>('%')); }
      break;

    case '^': // 颜色开始
      { formatters_.push_back(std::make_unique<CFormatterColorStart>(pad_info)); }
      break;

    case '$': // 颜色结束
      { formatters_.push_back(std::make_unique<CFormatterColorEnd>(pad_info)); }
      break;

    case '@': // 源文件定位
      { formatters_.push_back(std::make_unique<CFormatterSrcLocInfo<Padder>>(pad_info)); }
      break;

    case 'I': // 源文件文件名不带路径
      { formatters_.push_back(std::make_unique<CFormatterSrcShortFileName<Padder>>(pad_info)); }
      break;

    case 'i': // 源文件文件名带路径
      { formatters_.push_back(std::make_unique<CFormatterSrcFileName<Padder>>(pad_info)); }
      break;

    case '#': // 源文件行号
      { formatters_.push_back(std::make_unique<CFormatterSrcLineNum<Padder>>(pad_info)); }
      break;

    case '!': // 源文件函数名
      { formatters_.push_back(std::make_unique<CFormatterSrcFunctionName<Padder>>(pad_info)); }
      break;

    case 'g': // 距离上次日志时间 纳秒
      { formatters_.push_back(std::make_unique<CFormatterElapsed<Padder, RNanoseconds>>(pad_info)); }
      break;

    case 'f': // 距离上次日志时间 微秒
      { formatters_.push_back(std::make_unique<CFormatterElapsed<Padder, RMicroseconds>>(pad_info)); }
      break;

    case 'e': // 距离上次日志时间 毫秒
      { formatters_.push_back(std::make_unique<CFormatterElapsed<Padder, RMilliseconds>>(pad_info)); }
      break;

    case 's': // 距离上次日志时间 秒
      { formatters_.push_back(std::make_unique<CFormatterElapsed<Padder, RSeconds>>(pad_info)); }
      break;

    default:
      {
        auto unkown_falg = std::make_unique<CFormatterString>();
        unkown_falg->AddChar('%');
        unkown_falg->AddChar(flag);
        formatters_.push_back(std::move(unkown_falg));
      }
      break;
  }
}

SPadInfo CFormaterPattern::HandlePadSpec(std::string::const_iterator& iter, std::string::const_iterator end) {
  const size_t max_width = 64;
  if (end == iter) {
    return SPadInfo{};
  }

  SPadInfo::EPadSide side;

  switch (*iter) {
    case '-':
      {
        side = SPadInfo::kPadSideRight;
        ++iter;
      }
      break;
    case '=':
      {
        side = SPadInfo::kPadSideCenter;
        ++iter;
      }
      break;
    default:
      {
        side = SPadInfo::kPadSideLeft;
      }
      break;
  }

  if (end == iter || !std::isdigit(static_cast<unsigned char>(*iter))) {
    return SPadInfo{};
  }

  auto width = static_cast<size_t>(*iter) - '0';
  for (++iter; iter != end && std::isdigit(static_cast<unsigned char>(*iter)); ++iter) {
    auto dight = static_cast<size_t>(*iter) - '0';
    width = width * 10 + dight;
  }

  bool truncate;
  if (end != iter && '!' == *iter) {
    truncate = true;
    ++iter;
  } else {
    truncate = false;
  }

  return SPadInfo{std::min(width, max_width), side, truncate};
}

void CFormaterPattern::AnalyzePattern(const std::string& pattern) {
  auto end = pattern.end();
  std::unique_ptr<CFormatterString> user_chars;
  formatters_.clear();
  for (auto iter = pattern.begin(); iter != end; ++iter) {
    if ('%' == *iter) {
      if (user_chars) {
        formatters_.push_back(std::move(user_chars));
      }

      auto pad_info = HandlePadSpec(++iter, end);

      if (iter != end) {
        if (pad_info.Enabled()) {
          HandleFlag<CScopedPadder>(*iter, pad_info);
        } else {
          HandleFlag<CNullScopedPadder>(*iter, pad_info);
        }
      } else {
        break;
      }
    } else {
      if (!user_chars) {
        user_chars = std::make_unique<CFormatterString>();
      }
      user_chars->AddChar(*iter);
    }
  } // iter for
  if (user_chars) {
    formatters_.push_back(std::move(user_chars));
  }
}

} // !namespace log
} // !namespace afcore